package com.test;

import javax.swing.filechooser.FileSystemView;
import java.io.*;
import java.nio.channels.FileChannel;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * jdk17
 * 增量打包
 * 如果只想打包一个版本或者某一天的 只输入开始日期及开始版本号即可
 */
public class TestJDK17 {

    static String 项目名 = "";
    static String SVN地址 = "";
    static String 项目路径 = "";

    static String 开始日期 = "";
    static String 结束日期 = "";
    static Integer 开始版本号 = null;
    static Integer 结束版本号 = null;
    static String 更新包路径 = null;

    public static void main(String[] args)  {
        try {
            //更新包路径 打包放到桌面上
            更新包路径 = getUpdatePackageUrl();
            //打包
            pack(executeCommands(makeCommands()));
        } catch (IOException | ParseException e) {
            e.printStackTrace();
        }
    }

    /**
     * 生成更新包路径
     * @return
     */
    public static String getUpdatePackageUrl(){
        return FileSystemView.getFileSystemView().getHomeDirectory().getPath() + 项目名+String.format("%tF",new Date()).replaceAll("-","")+"更新包";
    }

    /**
     * 拼接命令
     * @return
     * @throws ParseException
     */
    public static String makeCommands() throws ParseException {
        return 开始日期.isEmpty() ? "svn diff -r " + (开始版本号-1) + ":" + (结束版本号==null ? 开始版本号 : 结束版本号) + " --summarize " +SVN地址
                : "svn diff -r {" + 开始日期 + "}:{" + addOneDay(结束日期.isEmpty() ? 开始日期 : 结束日期) +"} --summarize " +SVN地址;
    }

    /**
     * 执行命令，并返回更新文件路径
     * @param command 命令
     * @return
     */
    public static List<String> executeCommands(String command) throws IOException {
        List<String> fileUrls = new ArrayList<>();
        Process process = Runtime.getRuntime().exec(command);
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))){
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
                fileUrls.add(line);
            }
            process.waitFor();
        } catch (IOException | InterruptedException e) {
            process.destroy();
            e.printStackTrace();
        }
        return fileUrls;
    }

    /**
     * 打包
     * @param fileUrls
     */
    public static void pack(List<String> fileUrls){
        for (String line:fileUrls) {
            line = line.replaceAll(" ","").substring(1);
            if(line.indexOf("/src")>0){
                line = line.substring(0,line.indexOf("/src")) + "/WebRoot/WEB-INF/classes" + line.substring(line.indexOf("/com"));
                line = line.indexOf(".java")>0 ? line.replace(".java",".class") : line;
            }
            String sourcePath = line.replace(SVN地址,项目路径);
            String targetPath = line.replace(SVN地址,更新包路径);
            int parentFolderSubscript = sourcePath.lastIndexOf("/");
            int fileExtensionSubscript = sourcePath.lastIndexOf(".");
            //保证svn提交的是文件而不是文件夹
            if(fileExtensionSubscript>parentFolderSubscript){
                targetPath = targetPath.substring(0,targetPath.lastIndexOf("/"));
                List<String> query = query(sourcePath.substring(0,parentFolderSubscript), sourcePath.substring(parentFolderSubscript + 1,fileExtensionSubscript));
                //防止含有内部类
                for (String sourcePathSon:query) {
                    copy(sourcePathSon,targetPath);
                }
            }else{//文件夹直接创建
                File file = new File(targetPath);
                if (!file.exists()) {
                    file.mkdirs();
                }
            }
        }
    }

    /**
     * 复制文件
     * @param sourcePath 文件全路径
     * @param targetPath 要复制的位置
     */
    public static void copy(String sourcePath,String targetPath){
        File file = new File(targetPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        File sourceFile = new File(sourcePath);
        File targetFile = new File(targetPath,sourceFile.getName());
        try (FileInputStream fileInputStream = new FileInputStream(sourceFile);
             FileOutputStream fileOutputStream = new FileOutputStream(targetFile);
             FileChannel sourceChannel = fileInputStream.getChannel();
             FileChannel targetChannel = fileOutputStream.getChannel()) {
             targetChannel.transferFrom(sourceChannel, 0, sourceChannel.size());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 返回向后推一天的日期
     * @param day 日期
     * @return
     * @throws ParseException
     */
    public static String addOneDay(String day) throws ParseException {
        SimpleDateFormat sdfInput = new SimpleDateFormat("yyyy-MM-dd");
        Date date = sdfInput.parse(day);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, 1); // 加上一天
        SimpleDateFormat sdfOutput = new SimpleDateFormat("yyyy-MM-dd");
        String nextDayStr = sdfOutput.format(calendar.getTime());
        return nextDayStr;
    }

    /**
     * 根据文件名右模糊查找文件 查询内部类
     * @param path
     * @param name
     * @return
     */
    public static List<String> query(String path,String name){
        List<String> list = new ArrayList<>();
        File directory = new File(path);
        if (directory.exists()) {
            File[] files = directory.listFiles();
            for (File file : files) {
                if (file.isDirectory()) {
                    continue; // 若需要包含子目录内容，去除此处注释并修改相应部分代码
                } else {
                    if (file.getName().startsWith(name)) {
                        list.add(file.getAbsolutePath());
                    }
                }
            }
        }
        return list;
    }

}
